]> dgit.raspbian.org Git - gnome-shell.git/commitdiff
unlockDialog: Create auth prompt on demand
authorGeorges Basile Stavracas Neto <georges.stavracas@gmail.com>
Mon, 2 Dec 2019 14:01:20 +0000 (11:01 -0300)
committerFlorian Müllner <florian.muellner@gmail.com>
Mon, 10 Feb 2020 22:30:52 +0000 (22:30 +0000)
AuthPrompt is the set of actors that contain the user avatar,
the username, and the password entry. With the removal of the
screen shield, the unlock dialog (be it UnlockDialog or the
LoginDialog) is always created, and in the case of UnlockDialog,
so is the auth prompt.

This is problematic, though, since for passwordless accounts,
the simple act of creating AuthPrompt authenticates the user,
and lifts the lock screen.

Create the AuthPrompt on demand in UnlockDialog.

https://gitlab.gnome.org/GNOME/gnome-shell/merge_requests/872

js/ui/unlockDialog.js

index ec08acd1cf1b49249f7d657d2a2147a77a6f1169..9b8cfd935286f2132e1128599ac583ed9fb406fd 100644 (file)
@@ -453,34 +453,9 @@ var UnlockDialog = GObject.registerClass({
         stack.add_child(this._clock);
         this._showClock();
 
-        this._authPrompt = new AuthPrompt.AuthPrompt(new Gdm.Client(), AuthPrompt.AuthPromptMode.UNLOCK_ONLY);
-        this._authPrompt.connect('failed', this._fail.bind(this));
-        this._authPrompt.connect('cancelled', this._fail.bind(this));
-        this._authPrompt.connect('reset', this._onReset.bind(this));
-        this._authPrompt.nextButton.label = _("Unlock");
-
-        this._promptBox.add_child(this._authPrompt);
-
         this.allowCancel = false;
 
-        let screenSaverSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.screensaver' });
-        if (screenSaverSettings.get_boolean('user-switch-enabled')) {
-            let otherUserLabel = new St.Label({ text: _("Log in as another user"),
-                                                style_class: 'login-dialog-not-listed-label' });
-            this._otherUserButton = new St.Button({ style_class: 'login-dialog-not-listed-button',
-                                                    can_focus: true,
-                                                    child: otherUserLabel,
-                                                    reactive: true });
-            this._otherUserButton.connect('clicked', this._otherUserClicked.bind(this));
-            this._promptBox.add_child(this._otherUserButton);
-        } else {
-            this._otherUserButton = null;
-        }
-
-        this._authPrompt.reset();
-        this._updateSensitivity(true);
-
-        Main.ctrlAltTabManager.addGroup(this, _("Unlock Window"), 'dialog-password-symbolic');
+        Main.ctrlAltTabManager.addGroup(this, _('Unlock Window'), 'dialog-password-symbolic');
 
         // Notifications
         this._notificationsBox = new NotificationsBox();
@@ -555,6 +530,58 @@ var UnlockDialog = GObject.registerClass({
             this._createBackground(i);
     }
 
+    _ensureAuthPrompt() {
+        if (this._authPrompt)
+            return;
+
+        this._authPrompt = new AuthPrompt.AuthPrompt(new Gdm.Client(), AuthPrompt.AuthPromptMode.UNLOCK_ONLY);
+        this._authPrompt.connect('failed', this._fail.bind(this));
+        this._authPrompt.connect('cancelled', this._fail.bind(this));
+        this._authPrompt.connect('reset', this._onReset.bind(this));
+        this._authPrompt.nextButton.label = _("Unlock");
+
+        this._promptBox.add_child(this._authPrompt);
+
+        let screenSaverSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.screensaver' });
+        if (screenSaverSettings.get_boolean('user-switch-enabled')) {
+            let otherUserLabel = new St.Label({
+                text: _('Log in as another user'),
+                style_class: 'login-dialog-not-listed-label',
+            });
+            this._otherUserButton = new St.Button({
+                style_class: 'login-dialog-not-listed-button',
+                can_focus: true,
+                child: otherUserLabel,
+                reactive: true,
+            });
+            this._otherUserButton.connect('clicked', this._otherUserClicked.bind(this));
+            this._promptBox.add_child(this._otherUserButton);
+        } else {
+            this._otherUserButton = null;
+        }
+
+        this._authPrompt.reset();
+        this._updateSensitivity(true);
+    }
+
+    _maybeDestroyAuthPrompt() {
+        let focus = global.stage.key_focus;
+        if (focus === null ||
+            (this._authPrompt && this._authPrompt.contains(focus)) ||
+            (this._otherUserButton && focus === this._otherUserButton))
+            this.grab_key_focus();
+
+        if (this._authPrompt) {
+            this._authPrompt.destroy();
+            this._authPrompt = null;
+        }
+
+        if (this._otherUserButton) {
+            this._otherUserButton.destroy();
+            this._otherUserButton = null;
+        }
+    }
+
     _updateSensitivity(sensitive) {
         this._authPrompt.updateSensitivity(sensitive);
 
@@ -575,7 +602,10 @@ var UnlockDialog = GObject.registerClass({
             opacity: 0,
             duration: CROSSFADE_TIME,
             mode: Clutter.AnimationMode.EASE_OUT_QUAD,
-            onComplete: () => this._promptBox.hide(),
+            onComplete: () => {
+                this._promptBox.hide();
+                this._maybeDestroyAuthPrompt();
+            },
         });
 
         this._clock.ease({
@@ -586,6 +616,8 @@ var UnlockDialog = GObject.registerClass({
     }
 
     _showPrompt() {
+        this._ensureAuthPrompt();
+
         if (this._activePage === this._promptBox)
             return;
 
@@ -649,7 +681,8 @@ var UnlockDialog = GObject.registerClass({
     }
 
     cancel() {
-        this._authPrompt.cancel();
+        if (this._authPrompt)
+            this._authPrompt.cancel();
     }
 
     addCharacter(unichar) {
@@ -658,6 +691,7 @@ var UnlockDialog = GObject.registerClass({
     }
 
     finish(onComplete) {
+        this._ensureAuthPrompt();
         this._authPrompt.finish(onComplete);
     }